﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoxelBlock;using Vector3Int = VoxelBlock.Vector3Int;

/// <summary>
/// 标准方向
/// </summary>
public enum VoxelDirection
{
    Right = 0, Left = 1, Up = 2, Down = 3, Front = 4, Break = 5
}


/// <summary>
/// 模型数据
/// </summary>
public sealed class VoxelMetadata3D
{
    public static float UVunit = 1;
    public static float MaxUVx = UVunit * 8;
    public static float MaxUVy = UVunit * 32;
    public static float eposelong = 0.2f;

    /// <summary>
    /// 共轭方向索引集
    /// </summary>
    public static readonly int[] ConjugateDirectionIndexs = new int[] { 1, 0, 3, 2, 5, 4 };


    public static readonly Vector3Int[] ConjugateDirectionVector3Ints = new Vector3Int[] {
        new Vector3Int(1, 0, 0),
        new Vector3Int(-1, 0, 0),
        new Vector3Int(0, 1, 0),
        new Vector3Int(0, -1, 0),
        new Vector3Int(0, 0, 1),
        new Vector3Int(0, 0, -1),
    };

    /// <summary>
    /// 标准三角面
    /// </summary>
    public static readonly int[] Tris = new int[] { 0, 1, 2, 2, 3, 0 };

    private static VoxelMetadata3D instance;
    public static void InstanceGet()
    {
        if (instance == null)
        {
            instance = new VoxelMetadata3D();
        }
    }
    public static VoxelMetadata3D Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new VoxelMetadata3D();
            }
            return instance;
        }
    }
    public static void SetInstance()
    {
        instance = new VoxelMetadata3D();
    }

    public Vector3[] GetVertices(int key, Vector3Int a_Point)
    {
        Vector3[] return_Vector3s = new Vector3[4];
        //cot_vertices[key].CopyTo(return_Vector3s, 0);
        return_Vector3s[0] = Vector3Int.Add(standardVertices[key][0], a_Point);
        return_Vector3s[1] = Vector3Int.Add(standardVertices[key][1], a_Point);
        return_Vector3s[2] = Vector3Int.Add(standardVertices[key][2], a_Point);
        return_Vector3s[3] = Vector3Int.Add(standardVertices[key][3], a_Point);

        return return_Vector3s;
    }


    public Vector3[] GetVertices(VoxelDirection a_key, Vector3 a_Point)
    {
        Vector3[] return_Vector3s = new Vector3[4];
        Vertices(a_key).CopyTo(return_Vector3s, 0);
        for (int i = 0; i < 4; i++)
        {
            return_Vector3s[i] += a_Point;
        }
        return return_Vector3s;
    }


    public Vector3[] GetNormals(int key, Vector3 a_Point)
    {
        Vector3[] return_Vector3s = new Vector3[4];
        cot_normals[key].CopyTo(return_Vector3s, 0);
        for (int i = 0; i < 4; i++)
        {
            return_Vector3s[i] += a_Point;
        }
        return return_Vector3s;
    }


    /// <summary>
    /// 标准方向顶点矩阵
    /// </summary>
    /// <param name="a_key"></param>
    /// <returns></returns>
    public Vector3Int[] Vertices(VoxelDirection a_key)
    {
        return standardVertices[(int)a_key];
        //switch (a_key)
        //{
        //    case VoxelDirection.Left:
        //        return cot_vertices[0];
        //    case VoxelDirection.Right:
        //        return cot_vertices[1];

        //    case VoxelDirection.Up:
        //        return cot_vertices[2];
        //    case VoxelDirection.Down:
        //        return cot_vertices[3];

        //    case VoxelDirection.Front:
        //        return cot_vertices[4];
        //    case VoxelDirection.Break:
        //        return cot_vertices[5];

        //    default:
        //        return null;
        //}
    }

    /// <summary>
    /// 标准方向法线矩阵
    /// </summary>
    /// <param name="a_key"></param>
    /// <returns></returns>
    public Vector3[] Normals(VoxelDirection a_key)
    {
        return cot_normals[(int)a_key];
        //switch (a_key)
        //{
        //    case VoxelDirection.Left:
        //        return cot_normals[0];
        //    case VoxelDirection.Right:
        //        return cot_normals[1];

        //    case VoxelDirection.Up:
        //        return cot_normals[2];
        //    case VoxelDirection.Down:
        //        return cot_normals[3];

        //    case VoxelDirection.Front:
        //        return cot_normals[4];
        //    case VoxelDirection.Break:
        //        return cot_normals[5];
        //    default:
        //        return null;
        //}
    }

    /// <summary>
    /// 标准顶点矩阵
    /// </summary>
    public readonly static Vector3Int[][] standardVertices = new Vector3Int[][]
     {

                new Vector3Int[]{
                            new Vector3Int(1,0 ,1),
                            new Vector3Int(1,0 ,0),
                            new Vector3Int(1,1 ,0),
                            new Vector3Int(1,1 ,1)
               },
                new Vector3Int[]{
                            new Vector3Int(0,0 ,0),
                            new Vector3Int(0,0 ,1),
                            new Vector3Int(0,1 ,1),
                            new Vector3Int(0,1 ,0)
               },
                new Vector3Int[]{
                            new Vector3Int(1,1 ,0),
                            new Vector3Int(0,1 ,0),
                            new Vector3Int(0,1 ,1),
                            new Vector3Int(1,1 ,1)
               },
                new Vector3Int[]{
                            new Vector3Int(1,0 ,1),
                            new Vector3Int(0,0 ,1),
                            new Vector3Int(0,0 ,0),
                            new Vector3Int(1,0 ,0)
                },

                new Vector3Int[]{
                            new Vector3Int(0,0 ,1),
                            new Vector3Int(1,0 ,1),
                            new Vector3Int(1,1 ,1),
                            new Vector3Int(0,1 ,1)
               },
                new Vector3Int[]{
                            new Vector3Int(1,0 ,0),
                            new Vector3Int(0,0 ,0),
                            new Vector3Int(0,1 ,0),
                            new Vector3Int(1,1 ,0)
               }
      };

    public readonly static Vector3[][] cot_normals = new Vector3[][]{

        new Vector3[]{
                        new Vector3(1 ,0 ,0),
                        new Vector3(1 ,0 ,0),
                        new Vector3(1 ,0 ,0),
                        new Vector3(1 ,0 ,0)
        },
        new Vector3[]{
                        new Vector3(-1 ,0 ,0),
                        new Vector3(-1 ,0 ,0),
                        new Vector3(-1 ,0 ,0),
                        new Vector3(-1 ,0 ,0)
        },
        new Vector3[]{
                        new Vector3(0 ,1 ,0),
                        new Vector3(0 ,1 ,0),
                        new Vector3(0 ,1 ,0),
                        new Vector3(0 ,1 ,0)
        },
        new Vector3[]{
                        new Vector3(0 ,-1 ,0),
                        new Vector3(0 ,-1 ,0),
                        new Vector3(0 ,-1 ,0),
                        new Vector3(0 ,-1 ,0)
        },
        new Vector3[]{
                        new Vector3(0 ,0 ,1),
                        new Vector3(0 ,0 ,1),
                        new Vector3(0 ,0 ,1),
                        new Vector3(0 ,0 ,1)
        },
        new Vector3[]{
                        new Vector3(0 ,0 ,-1),
                        new Vector3(0 ,0 ,-1),
                        new Vector3(0 ,0 ,-1),
                        new Vector3(0 ,0 ,-1)
        }

         };


    // public readonly Vector2[][] allDataUVs = new Vector2[6][];
    public readonly Vector2[] allDataUVs = new Vector2[256 * 4];


    //public Vector3[] allDataVertices = new Vector3[4096 * 6 * 4];
    public readonly Color[] allDataColors = new Color[6];

    void SetUV(int i, Vector2 _uvXY, Vector2[] array)
    {
         array[i * 4] = new Vector2((_uvXY.x * UVunit + UVunit - eposelong)/ MaxUVx ,(_uvXY.y * UVunit          + eposelong)/ MaxUVy );
         array[i * 4 + 1] = new Vector2((_uvXY.x * UVunit          + eposelong)/ MaxUVx, (_uvXY.y * UVunit          + eposelong)/ MaxUVy );
         array[i * 4 + 2] =  new Vector2((_uvXY.x * UVunit          + eposelong)/ MaxUVx, (_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy );
         array[i * 4 + 3] = new Vector2((_uvXY.x * UVunit + UVunit - eposelong) / MaxUVx, (_uvXY.y * UVunit + UVunit - eposelong) / MaxUVy);
    }


    void InItAllDatas()
    {
     //   /*
        for (int y = 0, i = 0; y < MaxUVy; y++)
        {
            for (int x = 0; x < MaxUVx; x++, i++)
            {
                Vector2 _uvXY = new Vector2(x, y);
                allDataUVs[i * 4] = new Vector2((_uvXY.x * UVunit + eposelong) / MaxUVx, (_uvXY.y * UVunit + UVunit - eposelong) / MaxUVy);
                allDataUVs[i * 4 + 1] = new Vector2((_uvXY.x * UVunit + UVunit - eposelong) / MaxUVx, (_uvXY.y * UVunit + UVunit - eposelong) / MaxUVy);
                allDataUVs[i * 4 + 2] = new Vector2((_uvXY.x * UVunit + UVunit - eposelong) / MaxUVx, (_uvXY.y * UVunit + eposelong) / MaxUVy);
                allDataUVs[i * 4 + 3] = new Vector2((_uvXY.x * UVunit + eposelong) / MaxUVx, (_uvXY.y * UVunit + eposelong) / MaxUVy);
            }
        }
     //   */


        //for (int i = 0; i < 6; i++)
        //{
        //    allDataUVs[i] = new Vector2[6 * 4];
        //}
        //int index = 0;
        //for (int i = 0; i < 6; i++)
        //{
        //    SetUV(index, new Vector2(0, 0), allDataUVs[i]);
        //}

        //index++;
        //for (int i = 0; i < 6; i++)
        //{
        //    SetUV(index, new Vector2(1, 0), allDataUVs[i]);
        //}

        //index++;
        //SetUV(index, new Vector2(2, 0), allDataUVs[0]);
        //SetUV(index, new Vector2(2, 0), allDataUVs[1]);
        //SetUV(index, new Vector2(3, 0), allDataUVs[2]);
        //SetUV(index, new Vector2(3, 0), allDataUVs[3]);
        //SetUV(index, new Vector2(2, 0), allDataUVs[4]);
        //SetUV(index, new Vector2(2, 0), allDataUVs[5]);

        //index++;
        //SetUV(index, new Vector2(4, 0), allDataUVs[0]);
        //SetUV(index, new Vector2(4, 0), allDataUVs[1]);
        //SetUV(index, new Vector2(5, 0), allDataUVs[2]);
        //SetUV(index, new Vector2(5, 0), allDataUVs[3]);
        //SetUV(index, new Vector2(4, 0), allDataUVs[4]);
        //SetUV(index, new Vector2(4, 0), allDataUVs[5]);

        //index++;
        //for (int i = 0; i < 6; i++)
        //{
        //    SetUV(index, new Vector2(6, 0), allDataUVs[i]);
        //}

        //index++;
        //SetUV(index, new Vector2(7, 0), allDataUVs[0]);
        //SetUV(index, new Vector2(7, 0), allDataUVs[1]);
        //SetUV(index, new Vector2(5, 0), allDataUVs[2]);
        //SetUV(index, new Vector2(5, 0), allDataUVs[3]);
        //SetUV(index, new Vector2(7, 0), allDataUVs[4]);
        //SetUV(index, new Vector2(7, 0), allDataUVs[5]);


        //Func<Vector3Int, int, int, int, Vector3> GetVector3s =
        //(a, x, y, z) =>
        //{
        //    return new Vector3(a.x + x, a.y + y, a.z + z);
        //};
        //for (int direction = 0; direction < 6; direction++)
        //{
        //    for (int z = 0, i = 0; z < 16; z++)
        //    {
        //        for (int y = 0; y < 16; y++)
        //        {
        //            for (int x = 0; x < 16; x++, i++)
        //            {
        //                allDataVertices[direction * CHUNL_LENGTH6 + i * 4] = GetVector3s(cot_vertices[direction][0], x, y, z);
        //                allDataVertices[direction * CHUNL_LENGTH6 + i * 4 + 1] = GetVector3s(cot_vertices[direction][1], x, y, z);
        //                allDataVertices[direction * CHUNL_LENGTH6 + i * 4 + 2] = GetVector3s(cot_vertices[direction][2], x, y, z);
        //                allDataVertices[direction * CHUNL_LENGTH6 + i * 4 + 3] = GetVector3s(cot_vertices[direction][3], x, y, z);
        //            }
        //        }
        //    }
        //}


        allDataColors[0] = new Color(0.8f, 0.8f, 0.8f);
        allDataColors[1] = new Color(0.8f, 0.8f, 0.8f);
        allDataColors[2] = new Color(1, 1, 1);
        allDataColors[3] = new Color(1, 1, 1);
        allDataColors[4] = new Color(0.9f, 0.9f, 0.9f);
        allDataColors[5] = new Color(0.9f, 0.9f, 0.9f);
    }


    Vector2[][] AllUVs = new Vector2[256][];

    public Vector2[] GetUV(int key)
    {
        return AllUVs[key];
    }

    /// <summary>
    /// 标准UV坐标集合
    /// </summary>
    /// <param name="a_Vector2">VOX坐标</param>
    /// <returns>模型UV信息</returns>
    public Vector2[] GetUV(Vector2Int a_Vector2)
    {
        Vector2 _uvXY = a_Vector2;
        Vector2[] UVs = new Vector2[] {
                 new Vector2((_uvXY.x * UVunit + UVunit - eposelong)/ MaxUVx ,(_uvXY.y * UVunit          + eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit          + eposelong)/ MaxUVx, (_uvXY.y * UVunit          + eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit          + eposelong)/ MaxUVx, (_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + UVunit - eposelong)/ MaxUVx ,(_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy )
        };
        return UVs;
    }

    public Vector2[] GetUV(int a_x, int a_y)
    {
        Vector2 _uvXY = new Vector2(a_x, a_y);
        Vector2[] UVs = new Vector2[] {
                 new Vector2((_uvXY.x * UVunit + eposelong)/ MaxUVx ,(_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + UVunit -    eposelong)/ MaxUVx,(_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + UVunit - eposelong)/ MaxUVx,(_uvXY.y * UVunit + eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + eposelong)/ MaxUVx ,(_uvXY.y * UVunit + eposelong)/ MaxUVy )
        };
        return UVs;
    }

    int[] m_MaxTris = new int[147456];
    Vector2[] m_MaxUV2s = new Vector2[98304];


    public Vector2[] allUV3 = new Vector2[256 * 4];


    public Vector2[][] unitUV2s = new Vector2[2][];

    Color[] directionShadow = new Color[6]{
        new Color(0.9f, 0.9f, 0.9f),
        new Color(0.9f, 0.9f, 0.9f),
        new Color(1, 1, 1),
        new Color(1, 1, 1),
        new Color(0.95f, 0.95f, 0.95f),
        new Color(0.95f, 0.95f, 0.95f),
    };
    float[] directionShadowColors =
    {
            0.9f,0.9f,
            1,1,
            0.95f,0.95f
    };


    public Color[] GetColors(int directionKey, byte[] colorShadow)
    {
        Color[] colors = new Color[4];
        float colorUnit = 1;

        for (int i = 0; i < 4; i++)
        {
            colors[i] = directionShadow[directionKey];

            switch (colorShadow[i])
            {
                case 0:
                    colors[i] = directionShadow[directionKey];
                    break;
                case 1:
                    colorUnit = directionShadowColors[directionKey] - 0.25f;
                    colors[i] = new Color(colorUnit, colorUnit, colorUnit);
                    colors[i] = Color.green;
                    break;
                case 2:
                    colorUnit = directionShadowColors[directionKey] - 0.35f;
                    colors[i] = new Color(colorUnit, colorUnit, colorUnit);
                    colors[i] = Color.yellow;
                    break;
                default:
                    colorUnit = directionShadowColors[directionKey] - 0.35f;
                    colors[i] = new Color(colorUnit, colorUnit, colorUnit);
                    colors[i] = Color.red;
                    break;
            }
        }
        return colors;
    }

    private VoxelMetadata3D()
    {
        instance = this;
        InItMaxTris();
        //InItAllUVs();

        InItAllDatas();
    }

    /// <summary>
    /// 对边
    /// </summary>
    public static int[][] voxel3DEdgeIndex = new int[6][];

    /// <summary>
    /// 对角
    /// </summary>
    public static int[][] voxel3DCornerIndex = new int[6][];
    
    public Texture2D shadows;
    void InItMaxTris()
    {
        for (int i = 0; i < 24576; i++)
        {
            m_MaxTris[i * 6 + 0] = Tris[0] + i * 4;
            m_MaxTris[i * 6 + 1] = Tris[1] + i * 4;
            m_MaxTris[i * 6 + 2] = Tris[2] + i * 4;
            m_MaxTris[i * 6 + 3] = Tris[3] + i * 4;
            m_MaxTris[i * 6 + 4] = Tris[4] + i * 4;
            m_MaxTris[i * 6 + 5] = Tris[5] + i * 4;
        }

        //float ep = 0.195f;
        float ep = 0;

        var unitUV2 = unitUV2s[0] = new Vector2[4];
        unitUV2[0] = new Vector2(0 + ep, 1 - ep);
        unitUV2[1] = new Vector2(1 - ep, 1 - ep);
        unitUV2[2] = new Vector2(1 - ep, 0 + ep);
        unitUV2[3] = new Vector2(0 + ep, 0 + ep);

        //unitUV2[0] = new Vector2(0 + ep, 1 - ep * 2);
        //unitUV2[1] = new Vector2(0.5f - ep  , 1 - ep * 2);
        //unitUV2[2] = new Vector2(0.5f - ep , 0 + ep * 2);
        //unitUV2[3] = new Vector2(0 + ep, 0 + ep * 2);


        unitUV2 = unitUV2s[1] = new Vector2[4];
        unitUV2[0] = new Vector2(0.5f + ep, 1 - ep * 2);
        unitUV2[1] = new Vector2(1 - ep, 1 - ep * 2);
        unitUV2[2] = new Vector2(1 - ep, 0 + ep * 2);
        unitUV2[3] = new Vector2(0.5f + ep, 0 + ep * 2);
        unitUV2 = unitUV2s[0];

        for (int i = 0; i < 24576; i++)
        {
            m_MaxUV2s[i * 4 + 0] = unitUV2[0];
            m_MaxUV2s[i * 4 + 1] = unitUV2[1];
            m_MaxUV2s[i * 4 + 2] = unitUV2[2];
            m_MaxUV2s[i * 4 + 3] = unitUV2[3];
        }

        Color shadowColor = Color.gray;

        ByteTo8Bool uv3Byte = new ByteTo8Bool(false);
        shadows = new Texture2D(64, 64);
        for (int y = 0; y < 64; y++)
        {
            for (int x = 0; x < 64; x++)
            {
                shadows.SetPixel(x, y, Color.white);
            }
        }

        float uv3Max = 16 * 4;
        for (int y = 0, i = 0; y < 16; y++)
        {
            for (int x = 0; x < 16; x++, i++)
            {
                Vector2Int nowZero = new Vector2Int(x * 3 + 1, y * 3 + 1);
                shadows.SetPixel(nowZero.x, nowZero.y, Color.white);
                uv3Byte.SetValue((byte)i);
                if (uv3Byte[0])
                {
                    shadows.SetPixel(nowZero.x, nowZero.y + 1, shadowColor);
                }
                if (uv3Byte[1])
                {
                    shadows.SetPixel(nowZero.x, nowZero.y - 1, shadowColor);
                }
                if (uv3Byte[2])
                {
                    shadows.SetPixel(nowZero.x - 1, nowZero.y , shadowColor);
                }
                if (uv3Byte[3])
                {
                    shadows.SetPixel(nowZero.x + 1, nowZero.y, shadowColor);
                }
                if (uv3Byte[4])
                {
                    shadows.SetPixel(nowZero.x + 1, nowZero.y + 1, shadowColor);
                }
                if (uv3Byte[5])
                {
                    shadows.SetPixel(nowZero.x - 1, nowZero.y - 1, shadowColor);
                }
                if (uv3Byte[6])
                {
                    shadows.SetPixel(nowZero.x - 1, nowZero.y + 1, shadowColor);
                }
                if (uv3Byte[7])
                {
                    shadows.SetPixel(nowZero.x + 1, nowZero.y - 1, shadowColor);
                }
                allUV3[i * 4 + 0] = new Vector2((nowZero.x + 1 ) / uv3Max, (nowZero.y ) / uv3Max);
                allUV3[i * 4 + 1] = new Vector2((nowZero.x ) / uv3Max, (nowZero.y ) / uv3Max);
                allUV3[i * 4 + 2] = new Vector2((nowZero.x ) / uv3Max, (nowZero.y + 1 ) / uv3Max);
                allUV3[i * 4 + 3] = new Vector2((nowZero.x + 1 ) / uv3Max, (nowZero.y + 1 ) / uv3Max);
            }
        }

        shadows.Apply();

        //System.IO.File.WriteAllBytes(@"C:\Users\Administrator\Desktop\alex.png", shadows.EncodeToPNG());

        /*
        Func<Vector3Int, int> getWorldIndex = (v) => {
           return v.x * 1 + v.y * 256 + v.z * 65536;
        };

        Func<Vector3Int, int , Vector3Int> getY = (v, k) => {
            return new Vector3Int(v.x, k, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getFY = (v, k) => {
            return new Vector3Int(v.x, -k, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getZ = (v, k) => {
            return new Vector3Int(v.x, v.y, k);
        };

        Func<Vector3Int, int, Vector3Int> getFZ = (v, k) => {
            return new Vector3Int(v.x, v.y, -k);
        };

        Func<Vector3Int, int, Vector3Int> getX = (v, k) => {
            return new Vector3Int(k, v.y, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getFX = (v, k) => {
            return new Vector3Int(-k, v.y, v.y);
        };

        Func<Vector3Int, int, Vector3Int> getOY = (v, k) => {
            return new Vector3Int(v.x, 1, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getFOY = (v, k) => {
            return new Vector3Int(v.x, -1, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getOZ = (v, k) => {
            return new Vector3Int(v.x, v.y, 1);
        };

        Func<Vector3Int, int, Vector3Int> getFOZ = (v, k) => {
            return new Vector3Int(v.x, v.y, -1);
        };

        Func<Vector3Int, int, Vector3Int> getOX = (v, k) => {
            return new Vector3Int(1, v.y, v.z);
        };

        Func<Vector3Int, int, Vector3Int> getFOX = (v, k) => {
            return new Vector3Int(-1, v.y, v.y);
        };

        Func<Vector3Int, int, Vector3Int> nowX;
        Func<Vector3Int, int, Vector3Int> nowY;
        Func<Vector3Int, int, Vector3Int> nowZ;


        Func<Vector3Int, int, Vector3Int>[][] allEdge = {
            new Func<Vector3Int, int, Vector3Int>[]{ getOX, getY, getZ },
            new Func<Vector3Int, int, Vector3Int>[]{ getFOX, getY, getFZ },
            new Func<Vector3Int, int, Vector3Int>[]{ getOY, getZ,  getX},
            new Func<Vector3Int, int, Vector3Int>[]{ getFOY, getFZ, getX},
            new Func<Vector3Int, int, Vector3Int>[]{ getOZ , getY, getFX },
            new Func<Vector3Int, int, Vector3Int>[]{ getFOZ, getY,  getX},
        };
        for (int i = 0; i < 6; i++)
        {
            Func<Vector3Int, int, Vector3Int>[] nowFunc = allEdge[i];
            Vector3Int nowValue = new Vector3Int(0, 0, 0);
            int[] nowIndexs = new int[4];
            voxel3DEdgeIndex[i] = nowIndexs;

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, 1);
            nowValue = nowFunc[2](nowValue, 0);
            nowIndexs[0] = getWorldIndex(nowValue);

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, -1);
            nowValue = nowFunc[2](nowValue, 0);
            nowIndexs[1] = getWorldIndex(nowValue);


            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, 0);
            nowValue = nowFunc[2](nowValue, -1);
            nowIndexs[2] = getWorldIndex(nowValue);

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, 0);
            nowValue = nowFunc[2](nowValue, 1);
            nowIndexs[3] = getWorldIndex(nowValue);


            nowIndexs = new int[4];
            voxel3DCornerIndex[i] = nowIndexs;

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, 1);
            nowValue = nowFunc[2](nowValue, 1);
            nowIndexs[0] = getWorldIndex(nowValue);

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, -1);
            nowValue = nowFunc[2](nowValue, -1);
            nowIndexs[1] = getWorldIndex(nowValue);


            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, 1);
            nowValue = nowFunc[2](nowValue, -1);
            nowIndexs[2] = getWorldIndex(nowValue);

            nowValue = new Vector3Int(0, 0, 0);
            nowValue = nowFunc[0](nowValue, 0);
            nowValue = nowFunc[1](nowValue, -1);
            nowValue = nowFunc[2](nowValue, 1);
            nowIndexs[3] = getWorldIndex(nowValue);
        }
        return;
        */

        Func<int, int, int, int> getWorldIndex = (x,y,z) => {
            return x * 1 + y * 256 + z * 65536;
        };

        int[]
      nowIndexs = new int[4];
        voxel3DEdgeIndex[0] = nowIndexs;
        nowIndexs[0] = getWorldIndex(1, 1, 0);
        nowIndexs[1] = getWorldIndex(1, -1, 0);
        nowIndexs[2] = getWorldIndex(1, 0, -1);
        nowIndexs[3] = getWorldIndex(1, 0, 1);
        nowIndexs = new int[4];
        voxel3DCornerIndex[0] = nowIndexs;
        nowIndexs[0] = getWorldIndex(1, 1, 1);
        nowIndexs[1] = getWorldIndex(1, -1, -1);
        nowIndexs[2] = getWorldIndex(1, 1, -1);
        nowIndexs[3] = getWorldIndex(1, -1, 1);


        nowIndexs = new int[4];
        voxel3DEdgeIndex[1] = nowIndexs;
        nowIndexs[0] = getWorldIndex(-1, 1, 0);
        nowIndexs[1] = getWorldIndex(-1, -1, 0);
        nowIndexs[2] = getWorldIndex(-1, 0, 1);
        nowIndexs[3] = getWorldIndex(-1, 0, -1);
        nowIndexs = new int[4];
        voxel3DCornerIndex[1] = nowIndexs;
        nowIndexs[0] = getWorldIndex(-1, 1, -1);
        nowIndexs[1] = getWorldIndex(-1, -1, 1);
        nowIndexs[2] = getWorldIndex(-1, 1, 1);
        nowIndexs[3] = getWorldIndex(-1, -1, -1);


        nowIndexs = new int[4];
        voxel3DEdgeIndex[2] = nowIndexs;
        nowIndexs[0] = getWorldIndex(0, 1, 1);
        nowIndexs[1] = getWorldIndex(0, 1, -1);
        nowIndexs[2] = getWorldIndex(-1, 1, 0);
        nowIndexs[3] = getWorldIndex(1, 1, 0);
        nowIndexs = new int[4];
        voxel3DCornerIndex[2] = nowIndexs;
        nowIndexs[0] = getWorldIndex(1, 1, 1);
        nowIndexs[1] = getWorldIndex(-1, 1, -1);
        nowIndexs[2] = getWorldIndex(-1, 1, 1);
        nowIndexs[3] = getWorldIndex(1, 1, -1);

        nowIndexs = new int[4];
        voxel3DEdgeIndex[3] = nowIndexs;
        nowIndexs[0] = getWorldIndex(0, -1, -1);
        nowIndexs[1] = getWorldIndex(0, -1, 1);
        nowIndexs[2] = getWorldIndex(-1, -1, 0);
        nowIndexs[3] = getWorldIndex(1, -1, 0);
        nowIndexs = new int[4];
        voxel3DCornerIndex[3] = nowIndexs;
        nowIndexs[0] = getWorldIndex(1, -1, -1);
        nowIndexs[1] = getWorldIndex(-1, -1, 1);
        nowIndexs[2] = getWorldIndex(-1, -1, -1);
        nowIndexs[3] = getWorldIndex(1, -1, 1);

        nowIndexs = new int[4];
        voxel3DEdgeIndex[4] = nowIndexs;
        nowIndexs[0] = getWorldIndex(0, 1, 1);
        nowIndexs[1] = getWorldIndex(0, -1, 1);
        nowIndexs[2] = getWorldIndex(1, 0, 1);
        nowIndexs[3] = getWorldIndex(-1, 0, 1);
        nowIndexs = new int[4];
        voxel3DCornerIndex[4] = nowIndexs;
        nowIndexs[0] = getWorldIndex(-1, 1, 1);
        nowIndexs[1] = getWorldIndex(1, -1, 1);
        nowIndexs[2] = getWorldIndex(1, 1, 1);
        nowIndexs[3] = getWorldIndex(-1, -1, 1);


        nowIndexs = new int[4];
        voxel3DEdgeIndex[5] = nowIndexs;
        nowIndexs[0] = getWorldIndex(0, 1, -1);
        nowIndexs[1] = getWorldIndex(0, -1, -1);
        nowIndexs[2] = getWorldIndex(-1, 0, -1);
        nowIndexs[3] = getWorldIndex(1, 0, -1);
        nowIndexs = new int[4];
        voxel3DCornerIndex[5] = nowIndexs;
        nowIndexs[0] = getWorldIndex(1, 1, -1);
        nowIndexs[1] = getWorldIndex(-1, -1, -1);
        nowIndexs[2] = getWorldIndex(-1, 1, -1);
        nowIndexs[3] = getWorldIndex(1, -1, -1);

        //edgeBlockIndexs[0] = chunkIndex - 272;
        //edgeBlockIndexs[1] = chunkIndex + 240;
        //edgeBlockIndexs[2] = chunkIndex - 17;
        //edgeBlockIndexs[3] = chunkIndex - 15;

        //float eposelong = 0;
        //float uv3unit = 2;
        //float uv3Max = 16;
        //for (int y = 0, i = 0; y < 4; y++)
        //{
        //    for (int x = 0; x < 4; x++, i++)
        //    {
        //        //if (i == 8)
        //        //{
        //        //    uv3unit = 3;
        //        //    Vector2 nowZero = new Vector2(x * 3 + 0, y * 3 + 0);
        //        //    allUV3[i * 4 + 0] = new Vector2((nowZero.x + uv3unit) / uv3Max, (nowZero.y) / uv3Max);
        //        //    allUV3[i * 4 + 1] = new Vector2((nowZero.x) / uv3Max, (nowZero.y) / uv3Max);
        //        //    allUV3[i * 4 + 2] = new Vector2((nowZero.x) / uv3Max, (nowZero.y + uv3unit) / uv3Max);
        //        //    allUV3[i * 4 + 3] = new Vector2((nowZero.x + uv3unit) / uv3Max, (nowZero.y + uv3unit) / uv3Max);
        //        //}
        //        //else
        //        {
        //            uv3unit = 2;
        //            Vector2 nowZero = new Vector2(x * 4 + 1, y * 4 + 1);
        //            allUV3[i * 4 + 0] = new Vector2( (nowZero.x + uv3unit - eposelong) / uv3Max, (nowZero.y           + eposelong) / uv3Max);
        //            allUV3[i * 4 + 1] = new Vector2( (nowZero.x           + eposelong) / uv3Max, (nowZero.y           + eposelong) / uv3Max);
        //            allUV3[i * 4 + 2] = new Vector2( (nowZero.x           + eposelong) / uv3Max, (nowZero.y + uv3unit - eposelong) / uv3Max);
        //            allUV3[i * 4 + 3] = new Vector2( (nowZero.x + uv3unit - eposelong) / uv3Max, (nowZero.y + uv3unit - eposelong) / uv3Max);
        //        }
        //    }
        //}

    }
    void InItAllUVs()
    {
        for (int y = 0, i = 0; y < MaxUVy; y++)
        {
            for (int x = 0; x < MaxUVx; x++, i++)
            {
                Vector2 _uvXY = new Vector2(x, y);
                Vector2[] UVs = new Vector2[] {
                 new Vector2((_uvXY.x * UVunit + eposelong)/ MaxUVx ,(_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + UVunit -    eposelong)/ MaxUVx,(_uvXY.y * UVunit + UVunit - eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + UVunit - eposelong)/ MaxUVx,(_uvXY.y * UVunit + eposelong)/ MaxUVy ),
                 new Vector2((_uvXY.x * UVunit + eposelong)/ MaxUVx ,(_uvXY.y * UVunit + eposelong)/ MaxUVy )
               };
                AllUVs[i] = UVs;
            }
        }
        
    }

   

    public int[] GetTris(int a_Standardlength)
    {
        int[] return_Tris = new int[a_Standardlength * 6];
        Array.Copy(m_MaxTris, 0, return_Tris, 0, a_Standardlength * 6);
        return return_Tris;
    }

    public Vector2[] GetUV2(int a_Standardlength)
    {
        Vector2[] returnArray = new Vector2[a_Standardlength * 4];
        Array.Copy(m_MaxUV2s, 0, returnArray, 0, a_Standardlength * 4);
        return returnArray;
    }
    public Vector2[] GetUV2sUnit(int key)
    {
        return unitUV2s[key];
    }

    public void SetUV2s(Vector2[] uv2, int index, int key)
    {
        var unitUV2 = unitUV2s[key];
        uv2[index + 0] = unitUV2[0];
        uv2[index + 1] = unitUV2[1];
        uv2[index + 2] = unitUV2[2];
        uv2[index + 3] = unitUV2[3];
    }

    
    //public  Vector3 GetVector3s(Vector3Int a, int x, int y, int z)
    //{
    //    return new Vector3(a.x + x, a.y + y, a.z + z);
    //}

}
